program tex_pack;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  smCommonTypes in '..\..\source\shared\smCommonTypes.pas',
  smExceptions in '..\..\source\shared\smExceptions.pas',
  smUtils in '..\..\source\shared\smUtils.pas',
  Lua in '..\..\source\shared\Lua.pas',
  D3DX9;

var
  man_TexName: AnsiString;
  full_TexName: String;
  texList: array of record
    fullName: String;
    sysName: AnsiString;
    offset: Cardinal;
  end;
  texStream: TMemoryStream;
  inpStream: Text;

  outStreamName: AnsiString;
  outStream: TFileStream;

  I: Integer;
  PrevPos: Cardinal;

begin

  texStream := TMemoryStream.Create();
  outStream := nil;

  try
    if ParamCount = 0 then
    begin
      WriteLn('Type texture file name with extension and press RETURN');
      WriteLn('Type `done` when finished');
      WriteLn;

      Write('Package name: ');
      ReadLn(outStreamName);
      outStream := TFileStream.Create(
          Format('data\%s.txp', [outStreamName]),
          fmCreate or fmOpenWrite or fmShareDenyWrite
        );

      ReadLn(man_TexName);
      while man_TexName <> 'done' do
      begin
        full_TexName := Format('data\gfx\%s', [String(man_TexName)]);
        if FileExists(full_TexName, False) then
        begin
          SetLength(texList, Length(TexList) + 1);
          with TexList[High(TexList)] do
          begin
            sysName := man_TexName;
            fullName := full_TexName;
          end;
        end
        else
          WriteLn('Texture doesn''t exist in ''data\gfx'' folder');

        ReadLn(man_TexName);
      end;

    end
    else
    begin
      // pack input
      if FileExists(ParamStr(1), False) then
      begin
        outStream := TFileStream.Create(
            ChangeFileExt(ExtractFileName(ParamStr(1)), '.txp'),
            fmCreate or fmOpenWrite or fmShareDenyWrite
          );

        AssignFile(inpStream, ParamStr(1));
        Reset(inpStream);
        while not Eof(inpStream) do
        begin
          ReadLn(inpStream, man_TexName);
          full_TexName := Format('data\gfx\%s', [String(man_TexName)]);

          if FileExists(full_TexName, False) then
          begin
            SetLength(texList, Length(texList) + 1);
            with texList[High(texList)] do
            begin
              sysName := man_TexName;
              fullName := full_TexName;
            end;
          end;
        end;

      end
      else
        Exit;

    end;

    // Writing offsets
    outStream.WriteWord(Length(texList));
    for I := 0 to High(texList) do
      with texList[I] do
      begin
        outStream.WriteString(sysName);
        offset  := outStream.Position;
        outStream.WriteDWord(0);
      end;

    // Writing texture data and it's position in file
    for I := 0 to High(texList) do
      with texList[I] do
      begin
        texStream.Clear();
        texStream.LoadFromFile(fullName);
        outStream.WriteDWord(texStream.Size);
        outStream.Write(texStream.Memory^, texStream.Size);

        PrevPos := outStream.Position;
        outStream.Seek(offset, soFromBeginning);
        outStream.WriteDWord(PrevPos - texStream.Size - 4);
        outStream.Position := PrevPos;
      end;

  finally
    for I := 0 to High(texList) do
      with texList[I] do
      begin
        Finalize(fullName);
        Finalize(sysName);
      end;
    SetLength(texList, 0);

    texStream.Free();
    if Assigned(outStream) then
      outStream.Free();
  end;

end.
